<template>
    <div class="chat"> 
        <HeadBar />
        <div class="area" ref="msgBox">
            <div class="window box">
                <div class="text">
                    <div v-for="(item, index) in talkList" :key="index">
                        <div v-if="item.role == 'user'">
                            <div class="user">
                                <div class="header">
                                    <img src="../../assets/img/images/user.png" alt="用户">
                                </div>
                                <div class="text-box">
                                    <div>{{ item.content }}</div>
                                </div>
                            </div>
                        </div>
                        <div v-else>
                            <div class="system">
                                <div class="header">
                                    <img src="@/assets/img/images/ai.png" alt="系统">
                                </div>
                                <div class="text-box">
                                    <!-- <div>{{ item.content }}</div> -->
                                    <div v-html="formatMd(item.content)"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="box" style="padding: 0 10px;">
            <div class="editable-box" >
                <div class="text-area">
                    <textarea v-model="text" @keydown.enter.prevent="handleEnter" placeholder="请输入内容...(Shift+Enter 换行，Enter 发送)"></textarea>
                </div>
                <div class="operate">
                    <span v-if="text != ''&&!loading" @click="sendText"><img src="@/assets/img/images/send.png" alt="发送"></span>
                    <span v-if="text == ''&&!loading" class="disabled"><img src="@/assets/img/images/sendNo.png" alt="无法发送"></span>
                    <span v-if="text == ''&&loading" @click="handleStop"><img src="@/assets/img/images/suspend.png" alt="中止"></span>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import HeadBar from '@/layout/HeadBar/index.vue'
import { ref, onMounted, nextTick, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { customChat } from '@/api/custom.js'
import { useChattingStore, useCacheStore } from '@/stores'
import { storeToRefs } from 'pinia'
import { onBeforeRouteLeave } from 'vue-router'
import MarkdownIt from 'markdown-it'
import { fetchStream } from '@/api/fetchStream.js'

const abortController = new AbortController();

const md = new MarkdownIt({
    html: false,
    linkify: true
})

const formatMd = (text) => {
    return md.render(text)
}

const cacheStore = useCacheStore()
const chattingStore = useChattingStore()
const { type, customId, fileId, prompt } = storeToRefs(useChattingStore())

const text = ref('')
const talkList = ref([])
const loading = ref(false)
const isStream = ref(true)  //是否流式返回

watch(() => customId.value, (nVal) => { 
    let cache = cacheStore.getChatCache(nVal)
    talkList.value = !cache ? [] : JSON.parse(cache)
    chattingStore.clearChat()
    chattingStore.switchChat(talkList.value)
})

onBeforeRouteLeave((to, from, next) => {
    if(chattingStore.chattingList.length > 0 && chattingStore.customId != null) {
        cacheStore.addChatCache(chattingStore.customId, JSON.stringify(chattingStore.chattingList))
    }
    next()
})


//滚动条到底部
const msgBox = ref(null)
const scrollBottm = () => {
    let el = msgBox.value;
    el.scrollTop = el.scrollHeight;
}

onMounted(() => {
    if(chattingStore.customId != null) {
        let cache = cacheStore.getChatCache(chattingStore.customId)
        talkList.value = !cache ? [] : JSON.parse(cache)
    }
    scrollBottm()
})

const handleEnter = (e) => {
    if (e.shiftKey) {
        // Shift+Enter：允许换行（手动插入换行符）
        text.value += '\n';
    } else {
        // 单独 Enter：触发提交
        sendText()
    }
}

const handleStop = () => {
    if (loading.value) {
        abortController.abort();
        loading.value = false;
    }
}

const splitTextIntoPairs = (text) => {
    // 将文本按每个字符分割成数组
    let result = [];
    for (let i = 0; i < text.length; i++) {
        let pair = text.substring(i, i + 1);
        result.push(pair);
    }
    return result;
}

const chartContent = ref("");
const sendText = () => {
    if(!customId.value){
        ElMessage({
            message: '请先选择会话',
            type: 'warning',
            duration: 2000
        })
        return
    }
    if (text.value != '') {
        talkList.value.push({
            role: 'user',
            content: text.value
        })
        chattingStore.addChat({ role: 'user', content: text.value })
        
        nextTick(() => {
            scrollBottm()
        })
        loading.value = true

        let requestData;
        if(fileId.value){
            requestData = [
                {
                    role: 'system',
                    content: "fileid://"+fileId.value 
                },
                {
                    role: 'system',
                    content: prompt.value
                },
                ...talkList.value
            ]
        }else{
            requestData = [
                {
                    role: 'system',
                    content: prompt.value
                },
                ...talkList.value
            ]
        }

        talkList.value.push({
            role: 'system',
            content: ''
        })
        if(isStream.value) {
            fetchStream({
                type: type.value,
                requestMsg: JSON.stringify(requestData),
            }, 
            abortController.signal,
            (response) => {
                try {
                    console.log(response)
                    text.value = ''
                    chartContent.value += response.data
                    talkList.value[talkList.value.length - 1].content = chartContent.value
                    nextTick(() => {
                        scrollBottm()
                    })
                } catch (error) {
                    loading.value = false
                    chartContent.value = ''
                }
            },
            () => {
                console.log(chartContent.value);
                loading.value = false
                chattingStore.addChat({ role: 'system', content: chartContent.value })
                chartContent.value = ''
            })
        } else {
            customChat({
                type: type.value,
                requestMsg: JSON.stringify(requestData),
            }).then(data => {
                console.log(data)
                text.value = ''
                splitTextIntoPairs(data).forEach((pair, index) => {
                    setTimeout(() => {
                        talkList.value[talkList.value.length - 1].content += pair
                        nextTick(() => {
                            scrollBottm()
                        })
                    }, index * 10)
                })
                loading.value = false
                chattingStore.addChat({ role: 'system', content: data })
            }).catch(() => {
                loading.value = false
            })
        }
    }
}


</script>

<style lang="scss" scoped>
$bottmHeight: 106px;
.chat {
    height: 100%;

    .area {
        overflow-y: auto;
        height: calc(100% - #{$headHeight} - #{$bottmHeight} - 5px);
    }
    .window {
        padding: 10px;
        position: relative;

        .text {
            width: 100%;
            height: 100%;
            padding: 0 10px;
            color: #333;
            margin-bottom: 6px;
            >div {
                >div {
                    .user {
                        display: flex;
                        flex-direction: row-reverse;
                        margin-bottom: 5px;
                        .header {
                            margin-left: 10px;
                        }
                        .text-box {
                            background: rgba($color: #cee0f5, $alpha: 0.5);
                        }
                    }
                    .user-read {
                        display: flex;
                        flex-direction: row-reverse;
                        margin-right: 40px;
                        margin-bottom: 20px;
                        img {
                            cursor: pointer;
                        }
                    }
                    .system {
                        display: flex;
                        margin-bottom: 5px;
                        .header {
                            margin-right: 10px;
                        }
                        .text-box {
                            background: rgba($color: #fff, $alpha: 0.5);
                        }
                    }
                    .system-read {
                        margin-left: 40px;
                        margin-bottom: 20px;
                        img {
                            cursor: pointer;
                        }
                    }
                    .header {
                        width: 30px;
                        height: 30px;
                        border-radius: 50%;
                        overflow: hidden;
                        img {
                            width: 100%;
                            height: 100%;
                        }
                    }
                    .text-box {
                        max-width: calc(100% - 40px);
                        padding: 10px;
                        border-radius: 8px;
                        background: rgba($color: #fff, $alpha: 0.2);
                        font-size: 16px;
                        line-height: 1.5;
                        >div {
                            white-space: pre-wrap;
                        }
                    }
                }
            }
        }

    }
    .editable-box {
        width: 100%;
        height: 96px;
        padding: 5px 10px;
        margin: 0 auto;
        border: 2px solid #badcf3;
        border-radius: 8px;
        transition: all 0.3s ease;
        box-shadow: 0 2px 6px 1px rgba(58, 125, 226, 0.3);

        .text-area {
            width: 100%;
            height: 54px;
            textarea {
                width: 100%;
                height: 100%;
                border: none;
                outline: none;
                resize: none;
                font-size: 16px;
                color: #3d3e3f;
                line-height: 1.5;
                background: inherit;
            }
            /* 设置textarea框提示内容的样式 */
            textarea::-webkit-input-placeholder{
                color: #b0b4b9;
            }/*webkit 内核浏览器*/
            textarea::-moz-placeholder{
                color: #b0b4b9;
            }/*Mozilla Firefox 19+*/
            textarea:-moz-placeholder{
                color: #b0b4b9;
            }/*Mozilla Firefox 4 to 18*/
            textarea:-ms-input-placeholder{
                color: #b0b4b9;
            }
        }

        .operate {
            display: flex;
            justify-content: flex-end;
            span {
                cursor: pointer;
                &.disabled {
                    cursor: not-allowed;
                }
            }
        }
    }

    /* 输入框聚焦效果 */
    .editable-box:focus-within {
        border-color: #38a2f8;
        box-shadow: 0 2px 12px rgba(100, 198, 240, 0.2);
    }

}
</style>